package org.zoomdev.zoom.lock.modules;

import org.zoomdev.zoom.aop.AopFactory;
import org.zoomdev.zoom.aop.annotations.NoEnhance;
import org.zoomdev.zoom.ioc.Ioc;
import org.zoomdev.zoom.ioc.IocKey;
import org.zoomdev.zoom.ioc.MethodParameterNamesGetter;
import org.zoomdev.zoom.ioc.annotations.IocBean;
import org.zoomdev.zoom.ioc.annotations.Module;
import org.zoomdev.zoom.ioc.annotations.ModuleInit;
import org.zoomdev.zoom.lock.LockExecutor;
import org.zoomdev.zoom.lock.LockFactory;
import org.zoomdev.zoom.lock.LockType;

import java.lang.reflect.Type;
import java.util.concurrent.locks.Lock;

@NoEnhance
@Module
public class CoreLockModule {

    /**
     * 默认锁
     */
    public static LockType lockType = LockType.object;

    /**
     * 和线程数量相当
     */
    public static int maxTotal = Integer.MAX_VALUE;

    @IocBean
    public LockFactory<Object> getObjectLock() {
        return new ObjectLockFactory(maxTotal);
    }

    @IocBean
    public LockFactory<Lock> getReentrantLockFactory() {
        return new DefaultLockFactory(maxTotal, lockType == LockType.fairLock);
    }


    @IocBean
    public LockFactory getLockFactory(Ioc ioc) {
        if (lockType == LockType.object) {
            return ioc.fetch(IocKey.genericType(LockFactory.class, new Type[]{Object.class}));
        }
        return ioc.fetch(IocKey.genericType(LockFactory.class, new Type[]{Lock.class}));
    }


    @ModuleInit
    public void init(AopFactory factory, Ioc ioc, MethodParameterNamesGetter getter) {
        factory.addFactory(new LockInterceptorFactory(getter, ioc), 0);
    }


    @IocBean
    public LockExecutor getLockExecutor(Ioc ioc, LockFactory factory) {
        if (lockType == LockType.object) {
            return new ObjectLockExecutor(factory);
        }
        return new DefaultLockExecutor(factory);
    }

}
